package com.je.gateway.router.dispatcher;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.gateway.util.DES;
import com.je.gateway.util.SpringContextHolder;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import java.util.List;

/**
 * 参数解密
 */
public class ParamDecryptDispatcher extends GatewayAbstractRestDispatcher {

    private static final Logger logger = LoggerFactory.getLogger(ParamDecryptDispatcher.class);
    /**
     * 匹配的URL
     */
    private static final String pattern = "/(.*)";
    /**
     * 加密参数名
     */
    private static final String PARAMS_KEY = "params-keys";
    /**
     * 默认密钥
     */
    private static final String DEFAULT_KEY1 = "JECLOUDDESCRYPT";
    /**
     * 默认加密字段
     */
    private static final String DEFAULT_PARAMS = "tableCode,funcCode,j_query,strData";

    private static final String DECRYPT_KEY = "systemDecryptCache";

    @Override
    public int getOrder() {
        return 1;
    }

    @Override
    public void init(Router router) {
        router.routeWithRegex(pattern)
                .failureHandler(this::onFailure)
                .handler(createBodyHandler())
                .handler(this::onRequest);
    }

    protected void onRequest(RoutingContext context) {
        RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate");
        Object enableObj = redisTemplate.opsForHash().get(DECRYPT_KEY,"JE_SYS_ENCRYPT");
        if (!"1".equals(enableObj)) {
            context.next();
            return;
        }

        //获取混淆参数名
        String paramsKeys = context.request().getHeader(PARAMS_KEY);
        if (StringUtils.isBlank(paramsKeys)) {
            paramsKeys = context.request().getParam(PARAMS_KEY);
        }

        Object settingValue = redisTemplate.opsForHash().get(DECRYPT_KEY,"JE_SYS_ENCRYPT_FIELD");
        //获取配置的参数
        String configedFields = settingValue == null ? DEFAULT_PARAMS : settingValue.toString();
        List<String> paramList = Splitter.on(",").splitToList(configedFields);

        if (Strings.isNullOrEmpty(paramsKeys)) {
            boolean flag = false;
            for (String eachParam : paramList) {
                if(context.request().params().contains(eachParam)){
                    flag = true;
                    break;
                }
            }
            if(flag){
                context.request().response().setStatusCode(HttpStatus.BAD_REQUEST.value()).end("系统已启用传输加密，不允许明文传输！");
                return;
            }
            context.next();
            return;
        }

        Object key1 = redisTemplate.opsForHash().get(DECRYPT_KEY,"JE_SYS_ENCRYPT_KEY1");
        logger.error("--------------key1:" + key1);
        //获取密钥
        String key = key1 == null?DEFAULT_KEY1:key1.toString();

        //获取随机参数名
        List<String> keyList = Splitter.on(",").splitToList(paramsKeys);


        if (paramList != null && keyList != null) {
            for (int i = 0; i < paramList.size(); i++) {
                String param = paramList.get(i);
                //获取参数值
                String value = context.request().getParam(keyList.get(i));
                //解密参数设置值
                if(!Strings.isNullOrEmpty(value)){
                    String devalue = new DES(key).decrypt(value);
                    logger.debug("Add decrypt parameter {} value {} to request!", param, devalue);
                    context.request().params().add(param, devalue);
                }
            }
        }
        context.next();
    }

    public static void main(String[] args) {
        DES des = new DES("jlKcLuCUhA6kpPDrgqT");
        String enFuncCode = des.decrypt("6ba3f10ced21cfab25e576cf548b03ae0c524964eed95394");
        String enTableCode = des.decrypt("6ee8881650996132963119685793a2fe25e576cf548b03ae07afc36cca77dbba81cceca4ffc28455cef0c8d58f989ce4c68cf3090a23df626cc694cbe815412ec973f155037112f896519db875868e4c963119685793a2fe064e2e4207b3a5b071d1bd0d6f1aaf32255f54f038a974cdd9e3978c9cfaa969");
        String enJquery = des.encryption("{}");
        System.out.println(enFuncCode);
        System.out.println(enTableCode);
        System.out.println(enJquery);
    }

}
